home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CD ROM Paradise Collection 4
/
CD ROM Paradise Collection 4 1995 Nov.iso
/
hobby
/
ast44src.zip
/
CHARTS2.C
< prev
next >
Wrap
C/C++ Source or Header
|
1995-02-11
|
30KB
|
896 lines
/*
** Astrolog (Version 4.40) File: charts2.c
**
** IMPORTANT NOTICE: The graphics database and chart display routines
** used in this program are Copyright (C) 1991-1995 by Walter D. Pullen
** (astara@u.washington.edu). Permission is granted to freely use and
** distribute these routines provided one doesn't sell, restrict, or
** profit from them in any way. Modification is allowed provided these
** notices remain with any altered or edited versions of the program.
**
** The main planetary calculation routines used in this program have
** been Copyrighted and the core of this program is basically a
** conversion to C of the routines created by James Neely as listed in
** Michael Erlewine's 'Manual of Computer Programming for Astrologers',
** available from Matrix Software. The copyright gives us permission to
** use the routines for personal use but not to sell them or profit from
** them in any way.
**
** The PostScript code within the core graphics routines are programmed
** and Copyright (C) 1992-1993 by Brian D. Willoughby
** (brianw@sounds.wa.com). Conditions are identical to those above.
**
** The extended accurate ephemeris databases and formulas are from the
** calculation routines in the program "Placalc" and are programmed and
** Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
** (alois@azur.ch). The use of that source code is subject to
** regulations made by Astrodienst Zurich, and the code is not in the
** public domain. This copyright notice must not be changed or removed
** by any user of this program.
**
** Initial programming 8/28,30, 9/10,13,16,20,23, 10/3,6,7, 11/7,10,21/1991.
** X Window graphics initially programmed 10/23-29/1991.
** PostScript graphics initially programmed 11/29-30/1992.
** Last code change made 1/29/1995.
*/
#include "astrolog.h"
/*
******************************************************************************
** Dual Chart Display Routines.
******************************************************************************
*/
/* Print out an aspect (or midpoint if -g0 switch in effect) grid of a */
/* relationship chart. This is similar to the ChartGrid() routine; however, */
/* here we have both axes labeled with the planets for the two charts in */
/* question, instead of just a diagonal down the center for only one chart. */
void ChartGridRelation()
{
char sz[cchSzDef];
int i, j, k, tot = cObj, temp;
#ifdef INTERPRET
if (us.fInterpret && !us.fGridConfig) {
InterpretGridRelation();
return;
}
#endif
PrintSz(" 2>");
for (temp = 0, i = 1; i <= cObj; i++) if (!ignore[i]) {
PrintCh(chV);
AnsiColor(kObjA[i]);
sprintf(sz, "%c%c%c", chObj3(i)); PrintSz(sz);
AnsiColor(kDefault);
temp++;
}
PrintSz("\n1 ");
for (i = 1; i <= tot; i++) if (!ignore[i]) {
PrintCh(chV);
AnsiColor(kSignA(SFromZ(cp2.obj[i])));
sprintf(sz, "%2d%c", (int)cp2.obj[i] % 30, chDeg0); PrintSz(sz);
AnsiColor(kDefault);
}
PrintSz("\nV ");
for (i = 1; i <= tot; i++) if (!ignore[i]) {
PrintCh(chV);
temp = SFromZ(cp2.obj[i]);
AnsiColor(kSignA(temp));
sprintf(sz, "%c%c%c", chSig3(temp)); PrintSz(sz);
AnsiColor(kDefault);
}
PrintL();
for (j = 1; j <= cObj; j++) if (!ignore[j])
for (k = 1; k <= 4; k++) {
if (k < 2)
PrintTab(chH, 3);
else if (k == 2) {
AnsiColor(kObjA[j]);
sprintf(sz, "%c%c%c", chObj3(j)); PrintSz(sz);
} else {
temp = SFromZ(cp1.obj[j]);
AnsiColor(kSignA(temp));
if (k == 3)
sprintf(sz, "%2d%c", (int)cp1.obj[j] - (temp-1)*30, chDeg0);
else
sprintf(sz, "%c%c%c", chSig3(temp));
PrintSz(sz);
}
if (k > 1)
AnsiColor(kDefault);
for (i = 1; i <= tot; i++) if (!ignore[i]) {
PrintCh((char)(k < 2 ? chC : chV));
temp = grid->n[i][j];
if (k > 1) {
if (i == j)
AnsiColor(kReverse);
AnsiColor(us.fGridConfig ? kSignA(temp) :
kAspA[temp]);
}
if (k < 2)
PrintTab(chH, 3);
else if (k == 2) {
if (us.fGridConfig)
sprintf(sz, "%c%c%c", chSig3(temp));
else
sprintf(sz, "%s", temp ? szAspectAbbrev[temp] : " ");
PrintSz(sz);
} else if (k == 3) {
if (us.fGridConfig) {
sprintf(sz, "%2d%c", grid->v[i][j]/60, chDeg0); PrintSz(sz);
} else
if (grid->n[i][j]) {
if (grid->v[i][j] < 6000)
sprintf(sz, "%c%2d", us.fAppSep ?
(grid->v[i][j] < 0 ? 'a' : 's') :
(grid->v[i][j] < 0 ? '-' : '+'), abs(grid->v[i][j])/60);
else
sprintf(sz, "%3d", abs(temp)/60);
PrintSz(sz);
} else
PrintSz(" ");
} else {
if (grid->n[i][j]) {
sprintf(sz, "%02d'", abs(grid->v[i][j])%60); PrintSz(sz);
} else
PrintSz(" ");
}
AnsiColor(kDefault);
}
PrintL();
}
}
/* Display all aspects between objects in the relationship comparison chart, */
/* one per line, in sorted order based on the total "power" of the aspects, */
/* as specified with the -r0 -a switch combination. */
void ChartAspectRelation()
{
char sz[cchSzDef];
int pcut = 30000, icut, jcut, phi, ihi, jhi, ahi, p, i, j, k, count = 0;
real ip, jp;
loop {
phi = -1;
/* Search for the next most powerful aspect in the aspect grid. */
for (i = 1; i <= cObj; i++) if (!ignore[i])
for (j = 1; j <= cObj; j++) if (!ignore[j])
if (k = grid->n[i][j]) {
ip = i <= oNorm ? objectinf[i] : 2.5;
jp = j <= oNorm ? objectinf[j] : 2.5;
p = (int)(aspectinf[k]*(ip+jp)/2.0*
(1.0-RAbs((real)(grid->v[i][j]))/60.0/aspectorb[k])*1000.0);
if ((p < pcut || (p == pcut && (i > icut ||
(i == icut && j > jcut)))) && p > phi) {
ihi = i; jhi = j; phi = p; ahi = k;
}
}
if (phi < 0) /* Exit when no less powerful aspect found. */
break;
pcut = phi; icut = ihi; jcut = jhi;
count++; /* Display the current aspect. */
#ifdef INTERPRET
if (us.fInterpret) { /* Interpret it if -I in effect. */
InterpretAspectRelation(jhi, ihi);
continue;
}
#endif
sprintf(sz, "%3d: ", count); PrintSz(sz);
PrintAspect(jhi, SFromZ(cp1.obj[jhi]), (int)RSgn(cp1.dir[jhi]), ahi,
ihi, SFromZ(cp2.obj[ihi]), (int)RSgn(cp2.dir[ihi]), 'A');
k = grid->v[ihi][jhi];
AnsiColor(k < 0 ? kWhite : kLtGray);
sprintf(sz, "- orb: %c%d,%02d'",
us.fAppSep ? (k < 0 ? 'a' : 's') : (k < 0 ? '-' : '+'),
abs(k)/60, abs(k)%60); PrintSz(sz);
AnsiColor(kDkGreen);
sprintf(sz, " - power:%6.2f\n", (real)phi/1000.0); PrintSz(sz);
AnsiColor(kDefault);
}
}
/* Display locations of all midpoints between objects in the relationship */
/* comparison chart, one per line, in sorted zodiac order from zero Aries */
/* onward, as specified with the -r0 -m switch combination. */
void ChartMidpointRelation()
{
char sz[cchSzDef];
int mcut = -1, icut, jcut, mlo, ilo, jlo, m, i, j, count = 0;
loop {
mlo = 21600;
/* Search for the next closest midpoint farther down in the zodiac. */
for (i = 1; i <= cObj; i++) if (!ignore[i])
for (j = 1; j <= cObj; j++) if (!ignore[j]) {
m = (grid->n[j][i]-1)*30*60 + grid->v[j][i];
if ((m > mcut || (m == mcut && (i > icut ||
(i == icut && j > jcut)))) && m < mlo) {
ilo = i; jlo = j; mlo = m;
}
}
if (mlo >= 21600) /* Exit when no midpoint farther in zodiac found. */
break;
mcut = mlo; icut = ilo; jcut = jlo;
count++; /* Display the current midpoint. */
#ifdef INTERPRET
if (us.fInterpret) { /* Interpret it if -I in effect. */
InterpretMidpointRelation(ilo, jlo);
continue;
}
#endif
sprintf(sz, "%4d: ", count); PrintSz(sz);
PrintZodiac((real)mlo/60.0);
PrintCh(' ');
PrintAspect(ilo, SFromZ(cp1.obj[ilo]), (int)RSgn(cp1.dir[ilo]), 0,
jlo, SFromZ(cp2.obj[jlo]), (int)RSgn(cp2.dir[jlo]), 'M');
AnsiColor(kDefault);
m = (int)(MinDistance(cp1.obj[ilo], cp2.obj[jlo])*60.0);
sprintf(sz, "-%4d%c%02d' degree span.\n", m/60, chDeg1, m%60);
PrintSz(sz);
}
}
/* Calculate any of the various kinds of relationship charts. This involves */
/* reading in and storing the planet and house positions for both charts, */
/* and then combining them in the main single chart in the proper manner. */
/* If the parameter 'fFile' is on, then we read the info for the two charts */
/* from files, otherwise use the info in preset "core" and "second" charts. */
void CastRelation(fFile)
bool fFile;
{
byte ignoreT[objMax];
CI ciT;
int i;
real ratio, t1, t2, t;
/* Read in and cast the first chart. */
if (fFile)
FInputData(is.szFile);
ciT = ciCore;
if (fFile)
ciTwin = ciCore;
else
ciCore = ciTwin;
t1 = CastChart(fTrue);
for (i = 1; i <= cSign; i++) {
cp1.cusp[i] = house[i];
cp1.house[i] = inhouse[i];
}
for (i = 1; i <= cObj; i++) {
cp1.obj[i] = planet[i];
cp1.alt[i] = planetalt[i];
cp1.dir[i] = ret[i];
}
/* Read in the second chart. */
if (fFile) {
FInputData(is.szFile2);
if (us.nRel == rcProgress) {
us.fProgress = fTrue;
is.JDp = MdytszToJulian(MM, DD, YY, TT, SS, ZZ);
ciCore = ciT;
}
} else
ciCore = ciT;
ciMain = ciCore;
if (us.nRel == rcTransit)
for (i = 1; i <= cObj; i++) {
ignoreT[i] = ignore[i];
ignore[i] = ignore[i] && ignore2[i];
}
t2 = CastChart(fTrue);
if (us.nRel == rcTransit)
for (i = 1; i <= cObj; i++)
ignore[i] = ignoreT[i];
for (i = 1; i <= cSign; i++) {
cp2.cusp[i] = house[i];
cp2.house[i] = inhouse[i];
}
for (i = 1; i <= cObj; i++) {
cp2.obj[i] = planet[i];
cp2.alt[i] = planetalt[i];
cp2.dir[i] = ret[i];
}
/* Now combine the two charts based on what relation we are doing. */
/* For the standard -r synastry chart, use the house cusps of chart1 */
/* and the planets positions of chart2. */
ratio = (real)us.nRatio1 / ((real)(us.nRatio1 + us.nRatio2));
if (us.nRel <= rcSynastry)
for (i = 1; i <= cSign; i++)
house[i] = cp1.cusp[i];
/* For the -rc composite chart, take the midpoints of the planets/houses. */
else if (us.nRel == rcComposite) {
for (i = 1; i <= cObj; i++) {
planet[i] = Ratio(cp1.obj[i], cp2.obj[i], ratio);
if (RAbs(cp2.obj[i] - cp1.obj[i]) > rDegHalf)
planet[i] = Mod(planet[i] + rDegMax*ratio);
planetalt[i] = Ratio(cp1.alt[i], cp2.alt[i], ratio);
ret[i] = Ratio(cp1.dir[i], cp2.dir[i], ratio);
}
for (i = 1; i <= cSign; i++) {
house[i] = Ratio(cp1.cusp[i], cp2.cusp[i], ratio);
if (RAbs(cp2.cusp[i] - cp1.cusp[i]) > rDegHalf)
house[i] = Mod(house[i] + rDegMax*ratio);
}
/* Make sure we don't have any 180 degree errors in house cusp */
/* complement pairs, which may happen if the cusps are far apart. */
for (i = 1; i <= cSign; i++)
if (MinDistance(house[sCap], Mod(house[i]-ZFromS(i+3))) > rDegQuad)
house[i] = Mod(house[i]+rDegHalf);
for (i = 1; i <= cSign; i++)
if (RAbs(MinDistance(house[i], planet[oAsc - 1 + i])) > rDegQuad)
planet[oAsc - 1 + i] = Mod(planet[oAsc - 1 + i]+rDegHalf);
/* For the -rm time space midpoint chart, calculate the midpoint time and */
/* place between the two charts and then recast for the new chart info. */
} else if (us.nRel == rcMidpoint) {
T = Ratio(t1, t2, ratio);
t = (T*36525.0)+rRound; is.JD = RFloor(t)+2415020.0; TT = RFract(t)*24.0;
ZZ = Ratio(DecToDeg(ciT.zon), DecToDeg(Zon), ratio);
SS = Ratio(DecToDeg(ciT.dst), DecToDeg(Dst), ratio);
TT -= ZZ;
if (TT < 0.0) {
TT += 24.0; is.JD -= 1.0;
}
JulianToMdy(is.JD, &MM, &DD, &YY);
OO = Ratio(DecToDeg(ciT.lon), DecToDeg(Lon), ratio);
if (RAbs(Lon-ciT.lon) > rDegHalf)
OO = Mod(OO+rDegMax*ratio);
AA = Ratio(DecToDeg(ciT.lat), DecToDeg(Lat), ratio);
TT = DegToDec(TT); SS = DegToDec(SS); ZZ = DegToDec(ZZ);
OO = DegToDec(OO); AA = DegToDec(AA);
ciMain = ciCore;
CastChart(fTrue);
/* There are a couple of non-astrological charts, which only require the */
/* number of days that have passed between the two charts to be done. */
} else
is.JD = RAbs(t2-t1)*36525.0;
ComputeInHouses();
}
/*
******************************************************************************
** Other Chart Display Routines.
******************************************************************************
*/
/* Given two objects and an aspect between them, or an object and a sign */
/* that it's entering, print if this is a "major" event, such as a season */
/* change or major lunar phase. This is called from the ChartInDay() */
/* searching and influence routines. Do an interpretation if need be too. */
void PrintInDay(source, aspect, dest)
int source, aspect, dest;
{
if (aspect == aSig) {
if (source == oSun) {
AnsiColor(kWhite);
if (dest == 1)
PrintSz(" (Vernal Equinox)"); /* If the Sun changes sign, */
else if (dest == 4) /* then print out if this */
PrintSz(" (Summer Solstice)"); /* is a season change. */
else if (dest == 7)
PrintSz(" (Autumnal Equinox)");
else if (dest == 10)
PrintSz(" (Winter Solstice)");
}
} else if (aspect > 0) {
if (source == oSun && dest == oMoo) {
if (aspect <= aSqu)
AnsiColor(kWhite);
if (aspect == aCon)
PrintSz(" (New Moon)"); /* Print out if the present */
else if (aspect == aOpp) /* aspect is a New, Full, */
PrintSz(" (Full Moon)"); /* or Half Moon. */
else if (aspect == aSqu)
PrintSz(" (Half Moon)");
}
}
PrintL();
#ifdef INTERPRET
if (us.fInterpret)
InterpretInDay(source, aspect, dest);
#endif
AnsiColor(kDefault);
}
/* Given two objects and an aspect (or one object, and an event such as a */
/* sign or direction change) display the configuration in question. This */
/* is called by the many charts which list aspects among items, such as */
/* the -a aspect lists, -m midpoint lists, -d aspect in day search and */
/* influence charts, and -t transit search and influence charts. */
void PrintAspect(obj1, sign1, ret1, asp, obj2, sign2, ret2, chart)
int obj1, sign1, ret1, asp, obj2, sign2, ret2;
char chart;
{
char sz[cchSzDef];
AnsiColor(kObjA[obj1]);
if (chart == 't' || chart == 'T')
PrintSz("trans ");
else if (chart == 'e' || chart == 'u' || chart == 'U')
PrintSz("progr ");
sprintf(sz, "%7.7s", szObjName[obj1]); PrintSz(sz);
AnsiColor(kSignA(sign1));
sprintf(sz, " %c%c%c%c%c",
ret1 > 0 ? '(' : (ret1 < 0 ? '[' : '<'), chSig3(sign1),
ret1 > 0 ? ')' : (ret1 < 0 ? ']' : '>')); PrintSz(sz);
AnsiColor(asp > 0 ? kAspA[asp] : kWhite);
PrintCh(' ');
if (asp == aSig)
sprintf(sz, "-->"); /* Print a sign change. */
else if (asp == aDir)
sprintf(sz, "S/%c", obj2 ? chRet : 'D'); /* Print a direction change. */
else if (asp == 0)
sprintf(sz, chart == 'm' ? "&" : "with");
else
sprintf(sz, "%s", szAspectAbbrev[asp]); /* Print an aspect. */
PrintSz(sz);
if (asp != aDir)
PrintCh(' ');
if (chart == 'A')
PrintSz("with ");
if (asp == aSig) {
AnsiColor(kSignA(obj2));
sprintf(sz, "%s", szSignName[obj2]); PrintSz(sz);
} else if (asp >= 0) {
AnsiColor(kSignA(sign2));
if (chart == 't' || chart == 'u' || chart == 'T' || chart == 'U')
PrintSz("natal ");
sprintf(sz, "%c%c%c%c%c ",
ret2 > 0 ? '(' : (ret2 < 0 ? '[' : '<'), chSig3(sign2),
ret2 > 0 ? ')' : (ret2 < 0 ? ']' : '>')); PrintSz(sz);
AnsiColor(kObjA[obj2]);
sprintf(sz, "%.10s", szObjName[obj2]); PrintSz(sz);
}
if (chart == 'D' || chart == 'T' || chart == 'U' ||
chart == 'a' || chart == 'A' || chart == 'm' || chart == 'M')
PrintTab(' ', 10-CchSz(szObjName[obj2]));
}
/* Based on the given chart information, display all the aspects taking */
/* place in the chart, as specified with the -D switch. The aspects are */
/* printed in order of influence determined by treating them as happening */
/* outside among transiting planets, such that rare outer planet aspects */
/* are given more power than common ones among inner planets. (This is */
/* almost identical to the -a list, except the influences are different.) */
void ChartInDayInfluence()
{
int source[MAXINDAY], aspect[MAXINDAY], dest[MAXINDAY];
real power[MAXINDAY];
char sz[cchSzDef];
int occurcount = 0, i, j, k, l, m;
/* Go compute the aspects in the chart. */
i = us.fAppSep;
us.fAppSep = fTrue; /* We always want applying vs. separating orbs. */
FCreateGrid(fFalse);
us.fAppSep = i;
/* Search through the grid and build up the list of aspects. */
for (j = 2; j <= cObj; j++) {
if (ignore[j])
continue;
for (i = 1; i < j; i++) {
if (ignore[i] || (k = grid->n[i][j]) == 0 || occurcount >= MAXINDAY)
continue;
source[occurcount] = i; aspect[occurcount] = k; dest[occurcount] = j;
l = grid->v[i][j];
power[occurcount] =
((i <= oNorm ? transitinf[i] : 2.0)/4.0)*
((j <= oNorm ? transitinf[j] : 2.0)/4.0)*
aspectinf[k]*(1.0-(real)abs(l)/60.0/GetOrb(i, j, k));
occurcount++;
}
}
/* Sort aspects by order of influence. */
for (i = 1; i < occurcount; i++) {
j = i-1;
while (j >= 0 && power[j] < power[j+1]) {
SwapN(source[j], source[j+1]);
SwapN(aspect[j], aspect[j+1]);
SwapN(dest[j], dest[j+1]);
SwapR(&power[j], &power[j+1]);
j--;
}
}
/* Now display each aspect line. */
for (i = 0; i < occurcount; i++) {
sprintf(sz, "%3d: ", i+1); PrintSz(sz);
j = source[i]; k = aspect[i]; l = dest[i];
PrintAspect(
j, SFromZ(planet[j]), (int)RSgn(ret[j]), k,
l, SFromZ(planet[l]), (int)RSgn(ret[l]), 'D');
m = grid->v[j][l];
AnsiColor(m < 0 ? kWhite : kLtGray);
sprintf(sz, "- %s%2d%c%02d'", m < 0 ? "app" : "sep",
abs(m)/60, chDeg1, abs(m)%60); PrintSz(sz);
AnsiColor(kDkGreen);
sprintf(sz, " - power:%6.2f", power[i]); PrintSz(sz);
PrintInDay(j, k, l);
}
}
/* Given an arbitrary day, determine what aspects are made between this */
/* transiting chart and the given natal chart, as specified with the -T */
/* switch, and display the transits in order sorted by influence. */
void ChartTransitInfluence(fProg)
bool fProg;
{
int source[MAXINDAY], aspect[MAXINDAY], dest[MAXINDAY];
real power[MAXINDAY];
byte ignore3[objMax];
char sz[cchSzDef];
int occurcount = 0, i, j, k, l, m;
/* Cast the natal and transiting charts as with a relationship chart. */
for (i = 1; i <= cSign; i++)
cp1.cusp[i] = house[i];
for (i = 1; i <= cObj; i++) {
cp1.obj[i] = planet[i];
cp1.dir[i] = ret[i];
}
ciCore = ciTwin;
if (us.fProgress = fProg) {
is.JDp = MdytszToJulian(MM, DD, YY, TT, SS, ZZ);
ciCore = ciMain;
}
CastChart(fTrue);
for (i = 1; i <= cSign; i++)
cp2.cusp[i] = house[i];
for (i = 1; i <= cObj; i++) {
cp2.obj[i] = planet[i];
cp2.dir[i] = ret[i];
}
/* Do a relationship aspect grid to get the transits. We have to make and */
/* restore three changes to get it right for this chart. (1) We make the */
/* natal planets have zero velocity so applying vs. separating is only a */
/* function of the transiter. (2) We force applying vs. separating orbs */
/* regardless if -ga or -ma is in effect or not. (3) Finally we tweak the */
/* main restrictions to allow for transiting objects not restricted. */
for (i = 1; i <= cObj; i++) {
ret[i] = cp1.dir[i];
cp1.dir[i] = 0.0;
ignore3[i] = ignore[i];
ignore[i] = ignore[i] && ignore2[i];
}
i = us.fAppSep;
us.fAppSep = fTrue;
FCreateGridRelation(fFalse);
us.fAppSep = i;
for (i = 1; i <= cObj; i++) {
cp1.dir[i] = ret[i];
ignore[i] = ignore3[i];
}
/* Loop through the grid, and build up a list of the valid transits. */
for (i = 1; i <= oNorm; i++) {
if (ignore2[i] || !FThing(i))
continue;
for (j = 1; j <= cObj; j++) {
if (ignore[j] || (k = grid->n[i][j]) == 0 || occurcount >= MAXINDAY)
continue;
source[occurcount] = i; aspect[occurcount] = k; dest[occurcount] = j;
l = grid->v[i][j];
power[occurcount] = transitinf[i]*
((j <= oNorm ? objectinf[j] : 2.0)/4.0)*aspectinf[k]*
(1.0-(real)abs(l)/60.0/GetOrb(i, j, k));
occurcount++;
}
}
/* After all transits located, sort them by their total power. */
for (i = 1; i < occurcount; i++) {
j = i-1;
while (j >= 0 && power[j] < power[j+1]) {
SwapN(source[j], source[j+1]);
SwapN(aspect[j], aspect[j+1]);
SwapN(dest[j], dest[j+1]);
SwapR(&power[j], &power[j+1]);
j--;
}
}
/* Now loop through list and display each transit in effect at the time. */
for (i = 0; i < occurcount; i++) {
k = aspect[i];
l = source[i];
sprintf(sz, "%3d: ", i+1); PrintSz(sz);
j = SFromZ(cp2.obj[l]);
PrintAspect(l, j, (int)RSgn(cp2.dir[l]), k,
dest[i], SFromZ(cp1.obj[dest[i]]), (int)RSgn(cp1.dir[dest[i]]),
(char)(fProg ? 'U' : 'T'));
m = grid->v[l][dest[i]];
AnsiColor(m < 0 ? kWhite : kLtGray);
sprintf(sz, "- %s%2d%c%02d'", m < 0 ? "app" : "sep",
abs(m)/60, chDeg1, abs(m)%60); PrintSz(sz);
AnsiColor(kDkGreen);
sprintf(sz, " - power:%6.2f", power[i]); PrintSz(sz);
if (k == aCon && l == dest[i]) { /* Print a small "R" for returns. */
AnsiColor(kWhite);
PrintSz(" R");
}
PrintL();
#ifdef INTERPRET
if (us.fInterpret)
InterpretTransit(l, k, dest[i]);
#endif
AnsiColor(kDefault);
}
}
/* Given the zodiac location of a planet in the sky and its declination, */
/* and a location on the Earth, compute the azimuth and altitude of where */
/* on the local horizon sky the planet would appear to one at the given */
/* location. A reference MC position at Greenwich is also needed for this. */
void EclToHorizon(azi, alt, planet, planetalt, lon, lat, mc)
real *azi, *alt, planet, planetalt, lon, lat, mc;
{
real lonz, latz;
lonz = RFromD(planet); latz = RFromD(planetalt);
EclToEqu(&lonz, &latz);
lonz = RFromD(Mod(DFromR(mc-lonz+lon)));
lonz = RFromD(Mod(DFromR(lonz-lon+rPiHalf)));
EquToLocal(&lonz, &latz, rPiHalf-lat);
*azi = rDegMax-DFromR(lonz); *alt = DFromR(latz);
}
/* Display a calendar for the given month in the chart, as specified with */
/* with the -K switch. When color is on, the title is white, weekends are */
/* highlighted in red, and the specific day in the chart is colored green. */
void ChartCalendarMonth()
{
char sz[cchSzDef];
int i, j, k;
AnsiColor(kWhite);
PrintTab(' ', 16-CchSz(szMonth[Mon]) >> 1);
sprintf(sz, "%s%5d\n", szMonth[Mon], Yea); PrintSz(sz);
for (i = 0; i < 7; i++) {
sprintf(sz, "%c%c%c", szDay[i][0], szDay[i][1], i < 6 ? ' ' : '\n');
PrintSz(sz);
}
j = DayOfWeek(Mon, 1, Yea);
AnsiColor(kDefault);
for (i = 0; i < j; i++) {
if (i == 0)
AnsiColor(kRainbowA[1]);
PrintSz("-- ");
if (i == 0)
AnsiColor(kDefault);
}
k = DayInMonth(Mon, Yea);
for (i = 1; i <= k; i = AddDay(Mon, i, Yea, 1)) {
if (i == (int)Day)
AnsiColor(kRainbowA[4]);
else if (j == 0 || j == 6)
AnsiColor(kRainbowA[1]);
sprintf(sz, "%2d", i); PrintSz(sz);
if (j == 0 || j == 6 || i == Day)
AnsiColor(kDefault);
if (j < 6) {
j++;
PrintCh(' ');
} else {
j = 0;
PrintL();
}
}
while (j > 0 && j < 7) {
if (j == 6)
AnsiColor(kRainbowA[1]);
j++;
sprintf(sz, "--%c", j < 7 ? ' ' : '\n'); PrintSz(sz);
}
AnsiColor(kDefault);
}
/* Display a calendar for the entire year given in the chart, as specified */
/* with the -Ky switch. This is just like twelve of the individual month */
/* calendars above displayed together, with same color highlights and all. */
void ChartCalendarYear()
{
char sz[cchSzDef];
int r, w, c, m, d, dy, p[3], l[3], n[3];
dy = DayOfWeek(1, 1, Yea);
for (r = 0; r < 4; r++) { /* Loop over one set of three months */
AnsiColor(kWhite);
for (c = 0; c < 3; c++) {
m = r*3+c+1;
PrintTab(' ', 16-CchSz(szMonth[m]) >> 1);
sprintf(sz, "%s%5d", szMonth[m], Yea); PrintSz(sz);
if (c < 2)
PrintTab(' ', 20 + MONTHSPACE -
(16-CchSz(szMonth[m]) >> 1) - CchSz(szMonth[m]) - 5);
}
PrintL();
for (c = 0; c < 3; c++) {
for (d = 0; d < 7; d++) {
sprintf(sz, "%c%c%c", szDay[d][0], szDay[d][1],
d < 6 || c < 2 ? ' ' : '\n'); PrintSz(sz);
}
if (c < 2)
PrintTab(' ', MONTHSPACE-1);
m = r*3+c+1;
p[c] = dy % 7;
l[c] = DayInMonth(m, Yea);
n[c] = 0;
dy += DaysInMonth(m, Yea);
}
for (w = 0; w < 6; w++) { /* Loop over one set of week rows */
for (c = 0; c < 3; c++) { /* Loop over one week in a month */
m = r*3+c+1;
d = 0;
if (w == 0)
while (d < p[c]) {
if (d == 0)
AnsiColor(kRainbowA[1]);
PrintSz("-- ");
if (d == 0)
AnsiColor(kDefault);
d++;
}
AnsiColor(kDefault);
while (d < 7 && n[c] < l[c]) {
n[c] = AddDay(m, n[c], Yea, 1);
if (n[c] == Day && m == Mon)
AnsiColor(kRainbowA[4]);
else if (d == 0 || d == 6)
AnsiColor(kRainbowA[1]);
sprintf(sz, "%2d%c", n[c], d < 6 || c < 2 ? ' ' : '\n');
PrintSz(sz);
if (d == 0 || d == 6 || (n[c] == Day && m == Mon))
AnsiColor(kDefault);
d++;
}
while (d < 7) {
if (d == 0 || d == 6)
AnsiColor(kRainbowA[1]);
sprintf(sz, "--%c", d < 6 || c < 2 ? ' ' : '\n'); PrintSz(sz);
if (d == 0)
AnsiColor(kDefault);
d++;
}
if (c < 2)
PrintTab(' ', MONTHSPACE-1);
}
}
if (r < 3)
PrintL();
}
AnsiColor(kDefault);
}
/* Display either a biorhythm chart or the time difference in various units */
/* between two charts, i.e. two types of relationship "charts" that aren't */
/* related in any way to planetary positions, as specified by either the */
/* -rb or -rd switches, respectively. */
void DisplayRelation()
{
char sz[cchSzDef];
int i;
#ifdef BIORHYTHM
int j;
real k, l;
#endif
/* If we are calculating the difference between two dates, then display */
/* the value and return, as with the -rd switch. */
if (us.nRel == rcDifference) {
PrintSz("Differences between the dates in the two charts:\n");
for (i = 1; i <= 7; i++) {
AnsiColor(kRainbowA[i]);
switch (i) {
case 1: sprintf(sz, "Years : %.0f", is.JD/365.25); break;
case 2: sprintf(sz, "Months : %.0f", is.JD/(365.25/12)); break;
case 3: sprintf(sz, "Weeks : %.0f", is.JD/7.0); break;
case 4: sprintf(sz, "Days : %.0f", is.JD); break;
case 5: sprintf(sz, "Hours : %.0f", is.JD*24.0); break;
case 6: sprintf(sz, "Minutes: %.0f", is.JD*24.0*60.0); break;
case 7: sprintf(sz, "Seconds: %.0f", is.JD*24.0*3600.0); break;
}
PrintSz(sz);
PrintL();
}
AnsiColor(kDefault);
return;
}
#ifdef BIORHYTHM
/* If we are doing a biorhythm (-rb switch), then we'll calculate it for */
/* someone born on the older date, at the time of the younger date. Loop */
/* through the week preceeding and following the date in question. */
is.JD = RFloor(is.JD + rRound);
for (is.JD -= 7.0, i = -7; i <= 7; i++, is.JD += 1.0) {
if (i == 0)
AnsiColor(kWhite);
else if (i == 1)
AnsiColor(kDefault);
sprintf(sz, "T%c%d Day%c:",
i < 0 ? '-' : '+', abs(i), abs(i) != 1 ? 's' : ' '); PrintSz(sz);
for (j = 1; j <= 3; j++) {
PrintCh(' ');
switch (j) {
case 1: k = brPhy; AnsiColor(kRed); PrintSz("Physical"); break;
case 2: k = brEmo; AnsiColor(kBlue); PrintSz("Emotional"); break;
case 3: k = brInt; AnsiColor(kGreen); PrintSz("Intellectual"); break;
}
AnsiColor(i ? kDefault : kWhite);
/* The biorhythm calculation is below. */
l = RBiorhythm(is.JD, k);
sprintf(sz, " at %c%3.0f%%", l < 0.0 ? '-' : '+', RAbs(l)); PrintSz(sz);
/* Print smiley face, medium face, or sad face based on current cycle. */
AnsiColor(kPurple);
sprintf(sz, " :%c", l > 50.0 ? ')' : (l < -50.0 ? '(' : '|'));
PrintSz(sz);
AnsiColor(i ? kDefault : kWhite);
if (j < 3)
PrintCh(',');
}
PrintL();
}
#endif /* BIORHYTHM */
}
/* charts2.c */